-- SkyPropM
-- Create by chendh
-- 天空之城附加属性系统

module("SkyPropM", package.seeall);

-- 所有的规则处理子模块
local rules = {};

local SKY_PROP_PATH     = "sky_prop";
local STONE_PROP_PATH   = "sky_stone_prop";
local ROUND_PROP_PATH   = "sky_round_prop"

-- 模块初始化
function init()
    -- 载入所有的规则处理子模块
    rules = LOAD_PATH("game/logic/module/sc_prop");
end

-- 检索信息
function query(id, path)
    local m = stoneTable[id]

    if not m or path == "" or not path then
        return m
    end

    return m[path];
end

-- 获取子规则
function queryRule(rule)
    if rules[rule] == "TBL" then
        rules[rule] = LOAD_RUN("game/logic/module/sky_prop/" .. rule);
    end

    return rules[rule];
end

-- 计算属性加成
function calcAddon(fighter, attrib, baseValue, allSkyProp)
    local rate = 0;
    local value = 0;
    local skyProp = allSkyProp or fighter.dbase:query(SKY_PROP_PATH, {});
    local baseAttrib = skyProp["base_attrib"] or {};
    local defenserAttrib = skyProp["defenser_attrib"] or {};
    local perAttrib = skyProp["permillage_attrib"] or {};
    local defenserPerAttrib = skyProp["defenser_permillage_attrib"] or {};

    -- 累计固定数值增加
    value = (baseAttrib[attrib] or 0) + (defenserAttrib[attrib] or 0);

    -- 计算总的增加的千分比
    rate = (perAttrib[attrib] or 0) + (defenserPerAttrib[attrib] or 0);

    local skyRoundProp = fighter.dbase:query(ROUND_PROP_PATH, {});
    for _, data in pairs(skyRoundProp) do
        baseAttrib = data["base_attrib"] or {};
        defenserAttrib = data["defenser_attrib"] or {};
        perAttrib = data["permillage_attrib"] or {};
        defenserPerAttrib = data["defenser_permillage_attrib"] or {};

        value = value + (baseAttrib[attrib] or 0) + (defenserAttrib[attrib] or 0);
        rate = rate + (perAttrib[attrib] or 0) + (defenserPerAttrib[attrib] or 0);
    end

    -- 累计千分比增加
    value = value + math.floor((baseValue + value) * rate / 1000);

    return value;
end

-- 计算属性加成
function calcAddonByData(fighterInfo, attrib, baseValue)
    local rate = 0;
    local value = 0;
    local skyProp = fighterInfo[SKY_PROP_PATH] or {};
    local stoneProp = fighterInfo[STONE_PROP_PATH] or {};
    local baseAttrib = skyProp["base_attrib"] or {};
    local stoneBaseAttrib = stoneProp["base_attrib"] or {};
    local perAttrib = skyProp["permillage_attrib"] or {};
    local stonePerAttrib = stoneProp["permillage_attrib"] or {};

    -- 累计固定数值增加
    value = (baseAttrib[attrib] or 0) +
        (stoneBaseAttrib[attrib] or 0);

    -- 计算总的增加的千分比
    rate = (perAttrib[attrib] or 0) +
        (stonePerAttrib[attrib] or 0);

    -- 累计千分比增加
    value = value + math.floor((baseValue + value) * rate / 1000);

    return value;
end

-- 清除战斗对象的过期属性
function clearRoundProp(fighter, round)
    local skyRoundProp = fighter.dbase:query(ROUND_PROP_PATH) or {};

    -- 清除过期属性
    for propRound, data in pairs(skyRoundProp) do
        if propRound > 0 and propRound < round then
            skyRoundProp[propRound] = nil;
        end
    end

    fighter.dbase:set(ROUND_PROP_PATH, skyRoundProp);
end

-- 删除战斗对象的某条附加属性
function deleteFighterProp(fighter, rule)
    local prop;
    local skyProp = fighter.dbase:query(SKY_PROP_PATH) or {};

    prop = skyProp[rule];
    if not prop then
        return true;
    end

    skyProp[rule] = nil;

    return true;
end

-- 获取天空战战斗对象的附加属性
function getFighterProp(fighter, rule)
    local skyProp = fighter.dbase:query(SKY_PROP_PATH) or {};
    local mob = queryRule(rule);

    -- 先获取临时属性
    local value = getFighterRoundProp(fighter, rule);

    if not skyProp[rule] then
        return value;
    end

    return mob.mergeSkyProp(value, skyProp[rule]);
end

-- 获取战斗对象的天空战临时附加属性
function getFighterRoundProp(fighter, rule)
    local skyRoundProp = fighter.dbase:query(ROUND_PROP_PATH) or {};
    local mob = queryRule(rule);

    local value = mob.getEmptyProp();

    -- 合并所有回合的附加属性
    for round, data in pairs(skyRoundProp) do
        if data[rule] then
            value = mob.mergeSkyProp(value, data[rule])
        end
    end

    return value;
end

-- TODO: 获取prop的效果描述，给秘宝用的
function getDesc(prop)
    local desc;
    for rule, value in pairs(prop) do
        local mob = queryRule(rule);

        if mob.getDesc then
            if desc then
                desc = spliceLocStr(desc .. getLocStr("comma"), mob.getDesc(value));
            else
                desc = mob.getDesc(desc, value);
            end
        end
    end

    return desc;
end

-- 解析描述
function parseDesc(desc, prop)
    for rule, value in pairs(prop) do
        local mob = queryRule(rule);

        if mob.parseDesc then
            desc = mob.parseDesc(desc, value);
        end
    end

    return desc;
end

-- 附加战斗对象的天空战斗临时属性
function recordRoundProp(fighter, data, round)
    round = round or -1;

    local skyRoundProp = fighter.dbase:query(ROUND_PROP_PATH, {});
    skyRoundProp[round] = skyRoundProp[round] or {};

    local roundProp = skyRoundProp[round];

    for rule, value in pairs(data) do
        local mob = queryRule(rule);

        roundProp[rule] = mob.mergeSkyProp(roundProp[rule], value)
    end

    fighter.dbase:set(ROUND_PROP_PATH, skyRoundProp);
end


-- 刷新天空之城属性
function refreshSkyProp(user, petList)
    local result = {};
    local army = petList or SkyCombatM.getSkyArmy() or {};

    -- 刷新飞艇主炮附加的属性
    result = refreshAirshipSkillProp(user, result);

    -- 刷新僚机（飞艇链接）附加的属性
    result = refreshWingmanProp(user, result);

    -- 刷新秘宝附加的属性
    result = refreshPetSkillProp(user, army, result);

    -- 只有当不是为了某个特定的阵容而是使用当前阵容
    -- 计算的天空之城属性才记录到玩家属性里
    if not petList then
        user.dbase:set(SKY_PROP_PATH, result);
    end

    return result;
end

-- 刷新秘宝附加属性
function refreshPetSkillProp(user, petList, data)
    local skills = SkyShipSkillM.getActivityShipSkills(petList);

    for _, skillInfo in ipairs(skills) do
        repeat
            local propInfo = skillInfo["prop"];

            for rule, value in pairs(propInfo) do
                local mob = queryRule(rule);

                data[rule] = mob.mergeSkyProp(data[rule], value)
            end
        until true;
    end

    return data;
end

-- 刷新飞艇主炮附加的属性
function refreshAirshipSkillProp(user, data)
    local activeShip = NewAirShipM.getActiveAirShip();
    local skillId = NewAirShipM.getAirshipSKill(activeShip)
    local skillProp = SkyShipSkillM.query(skillId, "prop");

    for rule, value in pairs(skillProp) do
        local mob = queryRule(rule);

        data[rule] = mob.mergeSkyProp(data[rule], value)
    end

    return data;
end

-- 刷新防守方的秘宝附加属性（只在战斗中刷新战斗对象的属性时发现防守方没有天空属性时调用）
function refreshFighterSkillProp(fighter)
    local data = {};
    local skills = fighter:getAllSkills();

    for _, skillId in ipairs(skills) do
        local skillProp = SkyShipSkillM.query(skillId, "prop");

        for rule, value in pairs(skillProp) do
            local mob = queryRule(rule);

            data[rule] = mob.mergeSkyProp(data[rule], value)
        end
    end

    return data;
end

-- 刷新战斗对象的属性
function refreshFightersProp(attacker, defenser)
    local attackerSkyProp = attacker.dbase:query(SKY_PROP_PATH, {});
    local attackerSkyStoneProp = attacker.dbase:query(STONE_PROP_PATH, {});
    local defenserSkyProp = defenser.dbase:query(SKY_PROP_PATH, {});

    if #table.keys(defenserSkyProp) <= 0 then
        -- 防守方完全没有天空属性，那肯定是怪物或者BOSS，刷新下防守方的秘宝附加属性
        defenserSkyProp = refreshFighterSkillProp(defenser);
    end

    for rule, value in pairs(attackerSkyStoneProp) do
        local mob = queryRule(rule);

        attackerSkyProp[rule] = mob.mergeSkyProp(attackerSkyProp[rule], value)
    end

    attacker.dbase:delete(STONE_PROP_PATH);
    defenser.dbase:delete(STONE_PROP_PATH);

    -- 对对方附加的属性需要刷到对方身上
    local list = { "defenser_attrib", "defenser_permillage_attrib",
        "defenser_skill_rate", "defenser_disable_prop" };

    for _, rule in ipairs(list) do
        local temp = attackerSkyProp[rule];
        attackerSkyProp[rule] = defenserSkyProp[rule];
        defenserSkyProp[rule] = temp;
    end

    -- 都计算完了，记录到战斗对象身上
    attacker.dbase:set(SKY_PROP_PATH, attackerSkyProp);
    defenser.dbase:set(SKY_PROP_PATH, defenserSkyProp);

    -- 尝试触发交互属性
    triggerProp(attacker, "swap_attrib", {["target"] = defenser});

    -- 尝试复制四维
    triggerProp(attacker, "copy_attrib", {["target"] = defenser});
    triggerProp(defenser, "copy_attrib", {["target"] = attacker});

    -- 给双方刷满血
    attacker.dbase:set("hp", attacker:queryAttrib("fight_ability"));
    defenser.dbase:set("hp", defenser:queryAttrib("fight_ability"));
end

-- 刷新僚机（飞艇链接）附加的属性
function refreshWingmanProp(user, data)
    local wingMan = NewAirShipM.getWingman();

    for _, shipId in ipairs(wingMan) do
        local skillId = NewAirShipM.getAirshipSKill(shipId)
        local skillProp = SkyShipSkillM.query(skillId, "prop");

        for rule, value in pairs(skillProp) do
            local mob = queryRule(rule);

            data[rule] = mob.mergeSkyProp(data[rule], value)
        end
    end

    return data;
end

-- 触发属性
function triggerProp(fighter, rule, para)
    local mob = queryRule(rule);

    return mob.triggerProp(fighter, para);
end